<?
require_once(dirname(__FILE__) . '/../../classes/report_interface.inc.php');

class LoggerModuleRobotsReportBaseClass 
{
    protected $database;

    public function __construct(LoggerDatabase $database) 
    {
        $this->database = $database;
    }

    public function GetData($date1, $date2, $robots, $start, $count)
    {
        $date1 = '\'' . mysql_escape_string($date1) . '\'';
        $date2 = '\'' . mysql_escape_string($date2) . '\'';

        $robotsWhere = '';
        if (is_array($robots) && count($robots) > 0)
        {
            $arRobotsWhere = array();
            foreach($robots as $robot)
            {
                $arRobotsWhere[] = intval($robot);
            }
            $robotsWhere = '`robot` IN (' . implode(',', $arRobotsWhere) . ') AND ';
        }

        $SelectSQL = 'SELECT `robot`, `s`.`string` AS `robotStr`, SUM(`summ`) AS `summ` FROM (';
        $SelectSQL .= 'SELECT `robot`, COUNT(*) AS `summ` FROM `[PREF]module_robots` ';
        $SelectSQL .= 'WHERE '.$robotsWhere.'`time`>='.$date1.' AND `time`<'.$date2.' + INTERVAL 1 DAY ';
        $SelectSQL .= 'GROUP BY `robot` ';
        $SelectSQL .= 'UNION ALL ';
        $SelectSQL .= 'SELECT `robot`, SUM(`count`) AS `summ` FROM `[PREF]module_robots_archive` ';
        $SelectSQL .= 'WHERE '.$robotsWhere.'`date`>='.$date1.' AND `date`<='.$date2.' ';
        $SelectSQL .= 'GROUP BY `robot`) ';
        $SelectSQL .= 'AS `__temp_query` ';
        $SelectSQL .= 'LEFT JOIN `[PREF]module_robots_strings` `s` ON `s`.`id`=`__temp_query`.`robot` ';
        $SelectSQL .= 'GROUP BY `robot` ';
        $SelectSQL .= 'ORDER BY `summ` DESC, `robot`';
        $SelectSQL .= 'LIMIT '.$start.','.$count;

        $data = array();
        $result = $this->database->Query($SelectSQL);
        if (!$result)
             trigger_error('Database Error: ' . $this->database->Error(), E_USER_ERROR);
        while ($row = $this->database->FetchAssoc($result))
        {
            $data[] = $row;
        }
        $this->database->FreeResult($result);
        return $data;
    }
    
    protected function GetDetailData($date1, $date2, $robot, $start, $count)
    {
        $date1 = '\'' . mysql_escape_string($date1) . '\'';
        $date2 = '\'' . mysql_escape_string($date2) . '\'';
        $robot = intval($robot);

        $SelectSQL = 'SELECT DATE_FORMAT(`r`.`time`, \'%d.%m.%Y\') AS `date`, DATE_FORMAT(`r`.`time`, \'%H:%i:%s\') AS `time`, `p`.`string` AS `pathStr`, `q`.`string` AS `queryStr` FROM `[PREF]module_robots` AS `r` ';
        $SelectSQL .= 'LEFT JOIN `[PREF]module_robots_strings` AS `p` ON `p`.`id`=`r`.`path` ';
        $SelectSQL .= 'LEFT JOIN `[PREF]module_robots_strings` AS `q` ON `q`.`id`=`r`.`query` ';
        $SelectSQL .= 'WHERE `time`>='.$date1.' AND `time`<'.$date2.' + INTERVAL 1 DAY AND `robot`='.$robot.' ';
        $SelectSQL .= 'ORDER BY `r`.`time` ';
        $SelectSQL .= 'LIMIT ' . $start . ',' . $count;

        $result = $this->database->Query($SelectSQL);
        if (!$result)
             trigger_error('Database Error: ' . $this->database->Error(), E_USER_ERROR);

        $data = array();
        while ($row = $this->database->FetchAssoc($result))
        {
            $data[] = $row;
        }
        $this->database->FreeResult($result);

        return $data;
    }
    

    protected function GetUnknownData($date1, $date2, $start, $count)
    {
        $date1 = '\'' . mysql_escape_string($date1) . '\'';
        $date2 = '\'' . mysql_escape_string($date2) . '\'';

        $SelectSQL = 'SELECT `ip`, `agent` FROM `[PREF]module_robots_unknown` ';
        $SelectSQL .= 'WHERE `date`>='.$date1.' AND `date`<='.$date2.' ';
        $SelectSQL .= 'LIMIT '.$start.','.$count;

        $data = array();
        $result = $this->database->Query($SelectSQL);
        if (!$result)
             trigger_error('Database Error: ' . $this->database->Error(), E_USER_ERROR);
        while ($row = $this->database->FetchAssoc($result))
        {
            $data[] = $row;
        }
        $this->database->FreeResult($result);
        return $data;
    }

    protected function FormatUrlName($row)
    {
        $url = LoggerConfig::$myBaseUrl . $row['pathStr'];
        if ($row['queryStr'] != '')
            $url .= '?' . $row['queryStr'];

        $urlHuman = $url;
        if (strlen($urlHuman) > 100)
            $urlHuman = substr($urlHuman, 0, 97) . '...';

        return array(
            $url,
            $urlHuman
        );
    }
}








class LoggerModuleRobotsMainReport extends LoggerModuleRobotsReportBaseClass implements LoggerReportInterface
{
    public function __construct(LoggerDatabase $database) 
    {
        parent::__construct($database);
    }

    public function GetReport($root, $date1, $date2, $params = false)
    {
        $limit_start = 0;
        $limit_count = 100;

        $data = $this->GetData($date1, $date2, false, $limit_start, $limit_count);

        $xml = $root->ownerDocument;
        $name = $xml->createElement('report_name', 'Статистика работы роботов');
        $root->appendChild($name);
        $reportData = $xml->createElement('report_data');
        $root->appendChild($reportData);

        foreach($data as $row)
        {
            $dataRow = $xml->createElement('row');
            $reportData->appendChild($dataRow);
            $dataRow->setAttribute('robot', $row['robot']);
            $dataRow->setAttribute('robotStr', $row['robotStr']);
            $dataRow->setAttribute('count', $row['summ']);
        }

        $xsl = dirname(__FILE__) . '/templates/main.xsl';
        $pi = $xml->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="'.$xsl.'"');
        $xml->insertBefore($pi, $root);
        return true;
    }
}


class LoggerModuleRobotsUnknownReport extends LoggerModuleRobotsReportBaseClass implements LoggerReportInterface
{
    public function __construct(LoggerDatabase $database) 
    {
        parent::__construct($database);
    }

    public function GetReport($root, $date1, $date2, $params = false)
    {
        $limit_start = 0;
        $limit_count = 100;

        $data = $this->GetUnknownData($date1, $date2, $limit_start, $limit_count);

        $xml = $root->ownerDocument;
        $name = $xml->createElement('report_name', 'Неизвестные роботы');
        $root->appendChild($name);
        $reportData = $xml->createElement('report_data');
        $root->appendChild($reportData);

        foreach($data as $row)
        {
            $dataRow = $xml->createElement('row');
            $reportData->appendChild($dataRow);
            $dataRow->setAttribute('ip', $row['ip']);
            $dataRow->setAttribute('agent', $row['agent']);
        }

        if (count($data) == $limit_count)
        {
            $dataMore = $xml->createElement('report_data_more');
            $dataMore->setAttribute('start', $limit_count);
            $dataMore->setAttribute('count', $limit_count);
            $root->appendChild($dataMore);
        }

        $xsl = dirname(__FILE__) . '/templates/unknown.xsl';
        $pi = $xml->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="'.$xsl.'"');
        $xml->insertBefore($pi, $root);
        return true;
    }
}

class LoggerModuleRobotsUnknownMoreReport extends LoggerModuleRobotsReportBaseClass implements LoggerReportInterface
{
    public function __construct(LoggerDatabase $database) 
    {
        parent::__construct($database);
    }

    public function GetReport($root, $date1, $date2, $params = false)
    {
        if (!is_array($params) || !isset($params['start']) || !isset($params['robot']))
            return false;

        $limit_start = intval($params['start']);
        $limit_count = 100;

        if (isset($params['count']))
            $limit_count = intval($params['count']);

        $data = $this->GetUnknownData($date1, $date2, $limit_start, $limit_count);

        $xml = $root->ownerDocument;
        $reportData = $xml->createElement('report_data');
        $root->appendChild($reportData);

        foreach($data as $row)
        {
            $dataRow = $xml->createElement('row');
            $reportData->appendChild($dataRow);
            $dataRow->setAttribute('ip', $row['ip']);
            $dataRow->setAttribute('agent', $row['agent']);
        }

        $xsl = dirname(__FILE__) . '/templates/unknown_more.xsl';
        $pi = $xml->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="'.$xsl.'"');
        $xml->insertBefore($pi, $root);
        return true;
    }
}


class LoggerModuleRobotsByDateReport extends LoggerModuleRobotsReportBaseClass implements LoggerReportInterface
{
    public function __construct(LoggerDatabase $database) 
    {
        parent::__construct($database);
    }

    public function GetReport($root, $date1, $date2, $params = false)
    {

        $xml = $root->ownerDocument;
        
        $name = $xml->createElement('report_name', 'Статистика работы роботов');
        $root->appendChild($name);

//  Получаем список 5 самых активных роботов
        $data = $this->GetData($date1, $date2, false, 0, 5);
        $arRobots = array();
        foreach($data as $row)
        {
            $arRobots[$row['robot']] = $row['robotStr'];
        }

        $reportData = $xml->createElement('report_data');
        $root->appendChild($reportData);
        foreach($arRobots as $robotId => $robotStr)
        {
            $reportColumn = $xml->createElement('robot');
            $reportData->appendChild($reportColumn);
            $reportColumn->setAttribute('robotStr', $robotStr);
        }

        $timeStamp = strtotime($date1);
        $timeStop = strtotime($date2);
        while($timeStamp <= $timeStop)
        {
            $date = date('Y-m-d', $timeStamp);
//  На каждую дату получаем статистику по нужным роботам
            $data = $this->GetData($date, $date, array_keys($arRobots), 0, 5);

            $dataRow = $xml->createElement('row');
            $reportData->appendChild($dataRow);
            $dataRow->setAttribute('date', $date);
            $dataRow->setAttribute('dateHuman', date('d.m.Y', $timeStamp));
            foreach($arRobots as $robotId => $robotStr)
            {
                $reportColumn = $xml->createElement('robot');
                $dataRow->appendChild($reportColumn);
                $reportColumn->setAttribute('robotId', $robotId);
                $robotFound = false;
                if (is_array($data) && count($data) > 0)
                {
                    foreach ($data as $row)
                    {
                        if ($row['robot'] == $robotId)
                        {
                            $reportColumn->setAttribute('summ', $row['summ']);
                            $robotFound = true;
                            break;
                        }
                    }
                }
                if (!$robotFound)
                {
                    $reportColumn->setAttribute('summ', 0);
                }
            }
            $timeStamp = strtotime('+1 day', $timeStamp);
        }
    
        $xsl = dirname(__FILE__) . '/templates/by_date.xsl';
        $pi = $xml->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="'.$xsl.'"');
        $xml->insertBefore($pi, $root);
        return true;
    }
}


class LoggerModuleRobotsDetailReport extends LoggerModuleRobotsReportBaseClass implements LoggerReportInterface
{
    public function __construct(LoggerDatabase $database) 
    {
        parent::__construct($database);
    }

    public function GetReport($root, $date1, $date2, $params = false)
    {
        $limit_start = 0;
        $limit_count = 100;

        if (!isset($params['robot']))
            return false;
        $robot = intval($params['robot']);

        $robotStr = '';
        $SelectSQL = 'SELECT `string` FROM `[PREF]module_robots_strings` WHERE `id`='.intval($robot);
        $result = $this->database->Query($SelectSQL);
        if ($result && $row = $this->database->FetchAssoc($result))
        {
            $robotStr = $row['string'];
        }

        $xml = $root->ownerDocument;
        $name = $xml->createElement('report_name', 'Статистика работы робота ' . htmlspecialchars($robotStr));
        $root->appendChild($name);

        $SelectSQL = 'SELECT COUNT(*) AS `count`, MIN(`time`) as `minTime`, MAX(`time`) AS `maxTime` FROM `[PREF]module_robots`';
        $result = $this->database->Query($SelectSQL);
        if($result && ($row = $this->database->FetchAssoc($result)))
        {
            if ($row['count'] == 0)
            {
                $empty = $xml->createElement('empty');
                $root->appendChild($empty);
            }
            else
            {
                $minTime = strtotime($row['minTime']);
                $maxTime = strtotime($row['maxTime']);
    
                if ($minTime > strtotime($date1) || $maxTime < strtotime($date2))
                {
                    $incomplete = $xml->createElement('incomplete');
                    $incomplete->setAttribute('minDate', date('d.m.Y', $minTime));
                    $incomplete->setAttribute('maxDate', date('d.m.Y', $maxTime));
                    $root->appendChild($incomplete);
                }
            }
        }

        $reportData = $xml->createElement('report_data');
        $root->appendChild($reportData);

        $data = $this->GetDetailData($date1, $date2, $robot, $limit_start, $limit_count);

        foreach($data as $row)
        {
            list($url, $urlHuman) = $this->FormatUrlName($row);

            $dataRow = $xml->createElement('row');
            $reportData->appendChild($dataRow);
            $dataRow->setAttribute('date', $row['date']);
            $dataRow->setAttribute('time', $row['time']);
            $dataRow->setAttribute('url', $url);
            $dataRow->setAttribute('urlHuman', $urlHuman);
        }

        if (count($data) == $limit_count)
        {
            $dataMore = $xml->createElement('report_data_more');
            $dataMore->setAttribute('start', $limit_count);
            $dataMore->setAttribute('count', $limit_count);
            $dataMore->setAttribute('robot', $robot);
            $root->appendChild($dataMore);
        }

        $xsl = dirname(__FILE__) . '/templates/detail.xsl';
        $pi = $xml->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="'.$xsl.'"');
        $xml->insertBefore($pi, $root);
        return true;
    }
}

class LoggerModuleRobotsDetailMoreReport extends LoggerModuleRobotsReportBaseClass implements LoggerReportInterface
{
    public function __construct(LoggerDatabase $database) 
    {
        parent::__construct($database);
    }

    public function GetReport($root, $date1, $date2, $params = false)
    {
        if (!is_array($params) || !isset($params['start']) || !isset($params['robot']))
            return false;

        $limit_start = intval($params['start']);
        $limit_count = 100;

        if (isset($params['count']))
            $limit_count = intval($params['count']);

        $robot = $params['robot'];

        $xml = $root->ownerDocument;

        $reportData = $xml->createElement('report_data');
        $root->appendChild($reportData);

        $data = $this->GetDetailData($date1, $date2, $robot, $limit_start, $limit_count);

        foreach($data as $row)
        {
            list($url, $urlHuman) = $this->FormatUrlName($row);

            $dataRow = $xml->createElement('row');
            $reportData->appendChild($dataRow);
            $dataRow->setAttribute('date', $row['date']);
            $dataRow->setAttribute('time', $row['time']);
            $dataRow->setAttribute('url', $url);
            $dataRow->setAttribute('urlHuman', $urlHuman);
        }

        $xsl = dirname(__FILE__) . '/templates/detail_more.xsl';
        $pi = $xml->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="'.$xsl.'"');
        $xml->insertBefore($pi, $root);
        return true;
    }
}